| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 |
1
37
37
1
37
37
37
4
37
37
33
33
33
33
429
33
33
99
4
33
33
33
66
28
28
33
23
23
23
23
33
11
10
10
33
33
33
33
33
33
| 'use strict';
angular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])
.provider('$popover', function() {
var defaults = this.defaults = {
animation: 'am-fade',
customClass: '',
// uncommenting the next two lines will break backwards compatability
// prefixClass: 'popover',
// prefixEvent: 'popover',
container: false,
target: false,
placement: 'right',
template: 'popover/popover.tpl.html',
contentTemplate: false,
trigger: 'click',
keyboard: true,
html: false,
title: '',
content: '',
delay: 0,
autoClose: false
};
this.$get = function($tooltip) {
function PopoverFactory(element, config) {
// Common vars
var options = angular.extend({}, defaults, config);
var $popover = $tooltip(element, options);
// Support scope as string options [/*title, */content]
if(options.content) {
$popover.$scope.content = options.content;
}
return $popover;
}
return PopoverFactory;
};
})
.directive('bsPopover', function($window, $sce, $popover) {
var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;
return {
restrict: 'EAC',
scope: true,
link: function postLink(scope, element, attr) {
// Directive options
var options = {scope: scope};
angular.forEach(['template', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {
if(angular.isDefined(attr[key])) options[key] = attr[key];
});
// use string regex match boolean attr falsy values, leave truthy values be
var falseValueRegExp = /^(false|0|)$/i;
angular.forEach(['html', 'container', 'autoClose'], function(key) {
if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))
options[key] = false;
});
// should not parse target attribute (anchor tag), only data-target #1454
var dataTarget = element.attr('data-target');
Iif(angular.isDefined(dataTarget)) {
if(falseValueRegExp.test(dataTarget))
options.target = false;
else
options.target = dataTarget;
}
// Support scope as data-attrs
angular.forEach(['title', 'content'], function(key) {
attr[key] && attr.$observe(key, function(newValue, oldValue) {
scope[key] = $sce.trustAsHtml(newValue);
angular.isDefined(oldValue) && requestAnimationFrame(function() {
popover && popover.$applyPlacement();
});
});
});
// Support scope as an object
attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {
Eif(angular.isObject(newValue)) {
angular.extend(scope, newValue);
} else {
scope.content = newValue;
}
angular.isDefined(oldValue) && requestAnimationFrame(function() {
popover && popover.$applyPlacement();
});
}, true);
// Visibility binding support
attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {
if(!popover || !angular.isDefined(newValue)) return;
if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);
newValue === true ? popover.show() : popover.hide();
});
// Viewport support
attr.viewport && scope.$watch(attr.viewport, function (newValue) {
if(!popover || !angular.isDefined(newValue)) return;
popover.setViewport(newValue);
});
// Initialize popover
var popover = $popover(element, options);
// Garbage collection
scope.$on('$destroy', function() {
Eif (popover) popover.destroy();
options = null;
popover = null;
});
}
};
});
|